Friday, September 4, 2020

STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode

A character LCD has been an interesting staff for novice micro-controller learner. Prior to the present of C programming for micro-controller, the student used the Assembly language to program this character LCD. It requires a few dozens of Assembly codes.

STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode
Simulating Program In Proteus Using The STM32F103R6

Its original LCD controller was the Hitachi HD44780 chip. Currently it was replace by many other equivalent controller chip with low cost. For example, a 16x2 character LCD module costs around 1$. 

STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode
A typical character LCD module


STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode
A typical character LCD module

STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode
Its Pins Diagram

The interface between the micro-controller and this character LCD is a conventional parallel 8-bit data mode. However this LCD controller allow the program to use a 4-bit data transfer mode. You can see this tutorial for the LCD interface using 8-bit mode.

The LCD module is readable/writable. But we just write the command/data to this module is OK. The Register Select (RS) pin allow us to choose between command (RS=0) and data (RS=1). The Enable (E) pin allow the parallel data lath into the controller whenever there is a transition from High To Low. 

I use the STM32CubeIDE to write this code. It's very easy to use and it's free of charge. We need to register first before it allows us to download this IDE.

I select a number of output pin in code configuration wizard before it can generate the core source codes.

STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode
STM32F103R6 Pin Configuration In STM32CubeIDE

I need to write a few C functions to send the command and data to the LCD. And then I need to initialize the LCD module.

  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file : main.c
  5.   * @brief : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   * opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22.  
  23. /* Private function prototypes -----------------------------------------------*/
  24. void SystemClock_Config(void);
  25. static void MX_GPIO_Init(void);
  26.  
  27. /**
  28.   * @brief The application entry point.
  29.   * @retval int
  30.   */
  31. int main(void)
  32. {
  33. /* USER CODE BEGIN 1 */
  34.  
  35. /* USER CODE END 1 */
  36.  
  37. /* MCU Configuration--------------------------------------------------------*/
  38.  
  39. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  40. HAL_Init();
  41.  
  42. /* USER CODE BEGIN Init */
  43.  
  44. /* USER CODE END Init */
  45.  
  46. /* Configure the system clock */
  47. SystemClock_Config();
  48.  
  49. /* Initialize all configured peripherals */
  50. MX_GPIO_Init();
  51. lcdInit();
  52. lcdGotoXy(1,1);
  53. lcdPrint("STM32CubeIDE and");
  54. lcdGotoXy(1,2);
  55. lcdPrint("STM32F103R6 LCD");
  56. /* USER CODE BEGIN WHILE */
  57. while (1)
  58. {
  59.  
  60. }
  61. }
  62.  
  63. void delay(uint16_t num){
  64. for(uint16_t i=0;i<num;i++);
  65. }
  66.  
  67. void lcdCommand(uint16_t cmd){
  68. GPIOB->ODR=cmd<<2;
  69. //GPIOB->ODR&=~(1<<RS_Pin);
  70. HAL_GPIO_WritePin(RS_GPIO_Port,RS_Pin,GPIO_PIN_RESET);
  71. //GPIOB->ODR|=(1<<EN_Pin);
  72. HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);
  73. //HAL_Delay(1);
  74. delay(100);
  75. //GPIOB->ODR&=~(1<<EN_Pin);
  76. HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);
  77. //HAL_Delay(10);
  78. delay(10000);
  79. }
  80.  
  81. void lcdData(uint8_t data){
  82. GPIOB->ODR=data<<2;
  83. //GPIOB->ODR|=(1<<RS_Pin);
  84. HAL_GPIO_WritePin(RS_GPIO_Port,RS_Pin,GPIO_PIN_SET);
  85. //GPIOB->ODR|=(1<<EN_Pin);
  86. HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_SET);
  87. //HAL_Delay(1);
  88. delay(10);
  89. //GPIOB->ODR&=~(1<<EN_Pin);
  90. HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);
  91. //HAL_Delay(10);
  92. delay(1000);
  93. }
  94.  
  95. void lcdInit(void){
  96. //GPIOB->ODR&=~(1<<RS_Pin);
  97. HAL_GPIO_WritePin(EN_GPIO_Port,EN_Pin,GPIO_PIN_RESET);
  98. //HAL_Delay(2);
  99. delay(20000);
  100. lcdCommand(0x38);
  101. lcdCommand(0x0F);
  102. lcdCommand(0x01);
  103. //HAL_Delay(20);
  104. delay(20000);
  105. lcdCommand(0x06);
  106. }
  107.  
  108. void lcdGotoXy(unsigned char x,unsigned char y){
  109. unsigned char charAddr[]={0x80,0xC0,0x94,0xD4};
  110. lcdCommand(charAddr[y-1]+x-1);
  111. //HAL_Delay(1);
  112. delay(1000);
  113. }
  114.  
  115. void lcdPrint(char *str){
  116. unsigned char i=0;
  117. while(str[i]!=0){
  118. lcdData(str[i]);
  119. i++;
  120. }
  121. }
  122.  
  123. /**
  124.   * @brief System Clock Configuration
  125.   * @retval None
  126.   */
  127. void SystemClock_Config(void)
  128. {
  129. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  130. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  131.  
  132. /** Initializes the RCC Oscillators according to the specified parameters
  133.   * in the RCC_OscInitTypeDef structure.
  134.   */
  135. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  136. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  137. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  138. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  139. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  140. {
  141. Error_Handler();
  142. }
  143. /** Initializes the CPU, AHB and APB buses clocks
  144.   */
  145. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  146. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  147. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  148. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  149. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  150. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  151.  
  152. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  153. {
  154. Error_Handler();
  155. }
  156. }
  157.  
  158. /**
  159.   * @brief GPIO Initialization Function
  160.   * @param None
  161.   * @retval None
  162.   */
  163. static void MX_GPIO_Init(void)
  164. {
  165. GPIO_InitTypeDef GPIO_InitStruct = {0};
  166.  
  167. /* GPIO Ports Clock Enable */
  168. __HAL_RCC_GPIOB_CLK_ENABLE();
  169. __HAL_RCC_GPIOA_CLK_ENABLE();
  170.  
  171. /*Configure GPIO pin Output Level */
  172. HAL_GPIO_WritePin(GPIOB, RS_Pin|EN_Pin|GPIO_PIN_2|GPIO_PIN_3
  173. |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
  174. |GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
  175.  
  176. /*Configure GPIO pins : RS_Pin EN_Pin PB2 PB3
  177.   PB4 PB5 PB6 PB7
  178.   PB8 PB9 */
  179. GPIO_InitStruct.Pin = RS_Pin|EN_Pin|GPIO_PIN_2|GPIO_PIN_3
  180. |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
  181. |GPIO_PIN_8|GPIO_PIN_9;
  182. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  183. GPIO_InitStruct.Pull = GPIO_NOPULL;
  184. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  185. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  186.  
  187. }
  188.  
  189. /* USER CODE BEGIN 4 */
  190.  
  191. /* USER CODE END 4 */
  192.  
  193. /**
  194.   * @brief This function is executed in case of error occurrence.
  195.   * @retval None
  196.   */
  197. void Error_Handler(void)
  198. {
  199. /* USER CODE BEGIN Error_Handler_Debug */
  200. /* User can add his own implementation to report the HAL error return state */
  201. __disable_irq();
  202. while (1)
  203. {
  204. }
  205. /* USER CODE END Error_Handler_Debug */
  206. }
  207.  
  208. #ifdef USE_FULL_ASSERT
  209. /**
  210.   * @brief Reports the name of the source file and the source line number
  211.   * where the assert_param error has occurred.
  212.   * @param file: pointer to the source file name
  213.   * @param line: assert_param error line source number
  214.   * @retval None
  215.   */
  216. void assert_failed(uint8_t *file, uint32_t line)
  217. {
  218. /* USER CODE BEGIN 6 */
  219. /* User can add his own implementation to report the file name and line number,
  220.   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  221. /* USER CODE END 6 */
  222. }
  223. #endif /* USE_FULL_ASSERT */
  224.  
  225. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  226.  

Click here to download its source file.

For other similar posts please check,

  1. Getting Started With STM32F103C8T6 Module with STM32CubeIDE
  2.  STM32F103C8T6 Blue Pill SysTick and Multiplexing Display Example
  3.  STM32F103C8T6 Blue Pill Switch And Multiplexing Display Interface Using SysTick
  4.  STM32F103C8T6 Blue Pill SysTick LED Blinking
  5. STM32F103R6 Common Anode Seven Segments Display Example 
  6. STM32F103R6 Common Anode Seven Segments Display And Switch Interfacing 
  7. STM32F103R6 Simple 2-Digit Multiplexing Display And Switch Example 
  8. STM32F103R6 SysTick And Digital Clock Example 
  9. STM32F103R6 SysTick Two-Digit Multiplexing Display and Push Button
  10. LED Blinking With STM32F103R6 Using SysTick 
  11. STM32F103R6 SPI Interfaces To SN74HC595N Shift Registers 
  12. STM32F103R6 GPIO Interfaces To A Character LCD In 8-Bit Mode 
  13. STM32F103R6 SPI Interfaces To A Single Seven-Segment Display

No comments:

Post a Comment